import type { CSSProperties } from 'vue';

export type $AnimationMode = 'fade' | 'scale-bottom' | 'scale-left' | 'scale-right' | 'scale-top';

/**
 *得到布局
 */
export function getPlacement(
  sys: UniApp.GetSystemInfoResult,
  contentRect: { width: number; height: number },
  buttonRect: UniApp.NodeInfo,
  direction: 'auto' | 'bottom' | 'left' | 'right' | 'top'
) {
  // 箭头距离触发元素的距离
  const margin = 10;
  // 距离屏幕边缘的最小距离
  const mar = 8;
  // 箭头半径
  const arrowsRadius = 10 / 2;

  // 屏幕宽高
  const pageWidth = sys.windowWidth;
  const pageHeight = sys.windowHeight;
  // 点击dom宽高
  const targetWidth = buttonRect.width || 60;
  const targetHeight = buttonRect.height || 60;
  // 点击dom右上角的坐标
  const targeX = buttonRect.left || 0;
  const targeY = buttonRect.top || 0;
  // 点击dom中心点坐标
  const centerX = targeX + Math.trunc(targetWidth / 2);
  const centerY = targeY + Math.trunc(targetHeight / 2);
  // 弹出框的宽高
  const bubbleWidth = contentRect.width;
  const bubbleHeight = contentRect.height;

  // 上面足够
  const topEnough = Boolean(bubbleHeight + margin + mar < targeY);
  // 下面足够
  const bottomEnough = Boolean(targeY + targetHeight + bubbleHeight + margin + mar < pageHeight);
  // 左面足够
  const leftEnough = Boolean(targeX - bubbleWidth - margin - mar >= 0);
  // 右面足够
  const rightEnough = Boolean(targeX + targetWidth + bubbleWidth + margin + mar < pageWidth);
  // 屏幕宽度足够
  const widthEnough = Boolean(pageWidth > bubbleWidth + mar * 2);
  // 屏幕高度足够
  const heightEnough = Boolean(pageHeight > bubbleHeight + mar * 2);
  if (['auto', 'top'].includes(direction) && topEnough && widthEnough) {
    return getTopBottomPlacement('top');
  } else if (['auto', 'bottom'].includes(direction) && bottomEnough && widthEnough) {
    return getTopBottomPlacement('bottom');
  } else if (['auto', 'left'].includes(direction) && leftEnough && heightEnough) {
    return getLeftRightPlacement('left');
  } else if (['auto', 'right'].includes(direction) && rightEnough && heightEnough) {
    return getLeftRightPlacement('right');
  } else {
    const bubbleTop = Math.trunc(centerY + targetHeight / 2 + margin);
    return {
      enoughShow: false,
      mode: 'fade' as $AnimationMode,
      bubbleLeft: '0px',
      bubbleTop: `${bubbleTop}px`,
      arrowsTop: '0px',
      arrowsLeft: '0px',
    };
  }

  /** 上或者下足够并且宽度也足够 */
  function getTopBottomPlacement(placement: 'bottom' | 'top') {
    const bubbleTop = Math.trunc(placement === 'bottom' ? targeY + targetHeight + margin + sys.windowTop : targeY - bubbleHeight - margin + sys.windowTop);
    const rightX = Math.trunc(centerX - bubbleWidth / 2);
    const leftX = Math.trunc(centerX + bubbleWidth / 2);
    let bubbleLeft = mar;
    if (rightX >= mar && pageWidth - leftX >= mar) {
      bubbleLeft = rightX;
    } else if (pageWidth - leftX >= mar) {
      bubbleLeft = mar;
    } else if (rightX >= mar) {
      bubbleLeft = pageWidth - bubbleWidth - mar;
    }

    const arrowsTop = placement === 'bottom' ? -arrowsRadius : bubbleHeight - arrowsRadius - 4;
    //  减 5 的原因是箭头旋转后中心点变
    const arrowsLeft = centerX - bubbleLeft - 5;
    const mode: $AnimationMode = placement === 'top' ? 'scale-top' : 'scale-bottom';

    return {
      enoughShow: true,
      mode,
      bubbleTop: `${bubbleTop}px`,
      bubbleLeft: `${bubbleLeft}px`,
      arrowsTop: `${arrowsTop}px`,
      arrowsLeft: `${arrowsLeft}px`,
    };
  }

  /** 左或者右足够并且高度也足够 */
  function getLeftRightPlacement(placement: 'left' | 'right') {
    const bubbleLeft = Math.trunc(placement === 'left' ? targeX - bubbleWidth - margin : targeX + targetWidth + margin);
    const topY = Math.trunc(centerY - bubbleHeight / 2);
    const bottomY = Math.trunc(centerY + bubbleHeight / 2);

    const mode: $AnimationMode = placement === 'left' ? 'scale-left' : 'scale-right';

    let bubbleTop = mar + sys.windowTop;
    if (topY >= mar && pageHeight - bottomY >= mar) {
      // 水平居中
      bubbleTop = topY + sys.windowTop;
    } else if (pageHeight - bottomY >= mar) {
      bubbleTop = mar + sys.windowTop;
    } else {
      bubbleTop = pageHeight - bubbleHeight - mar + sys.windowTop;
    }
    const arrowsTop = centerY - bubbleTop - 5 + sys.windowTop;
    const arrowsLeft = placement === 'left' ? bubbleWidth - arrowsRadius - 2 : -arrowsRadius;
    return {
      enoughShow: true,
      mode,
      bubbleTop: `${bubbleTop}px`,
      bubbleLeft: `${bubbleLeft}px`,
      arrowsTop: `${arrowsTop}px`,
      arrowsLeft: `${arrowsLeft}px`,
    };
  }
}
/**
 * 得到动画
 */
export function getAmatons(mode: $AnimationMode, init: boolean): CSSProperties {
  let style: CSSProperties = {};
  if (mode === 'scale-top') {
    style = { transform: init ? 'scaleY(1)' : 'scaleY(0)', transformOrigin: 'center bottom', transitionProperty: 'transform' };
  } else if (mode === 'scale-bottom') {
    style = { transform: init ? 'scaleY(1)' : 'scaleY(0)', transformOrigin: 'center top', transitionProperty: 'transform' };
  } else if (mode === 'scale-left') {
    style = { transform: init ? 'scaleX(1)' : 'scaleX(0)', transformOrigin: 'right center', transitionProperty: 'transform' };
  } else if (mode === 'scale-right') {
    style = { transform: init ? 'scaleX(1)' : 'scaleX(0)', transformOrigin: 'left center', transitionProperty: 'transform' };
  } else {
    style = { opacity: init ? 1 : 0, transitionProperty: 'opacity' };
  }
  return style;
}
